package services

import (
	"context"
	"fmt"
	"github.com/sirupsen/logrus"
	"sync"
	"time"
	"wecom_rebot/common"
	"wecom_rebot/core"
	"wecom_rebot/utils"
)

var sendMsgLogger *logrus.Logger

// InitSendMessageLogger 移除 init() 函数，改为显式初始化函数
func InitSendMessageLogger() {
	// 确保在 common 初始化后调用
	sendMsgLogger = core.InitLogger(common.LogsErrorMap[7])
}

// TextMessage 定义文本消息结构体
type TextMessage struct {
	MsgType string `json:"msgtype"`
	Text    struct {
		Content string `json:"content"`
	} `json:"text"`
}

// FileMessage 定义文件消息结构体
type FileMessage struct {
	MsgType string `json:"msgtype"`
	File    struct {
		MediaId string `json:"media_id"`
	} `json:"file"`
}

// BendiSendText 发送消息错误函数
func BendiSendText(message, roomID, sender string) error {
	var sendURLs []string
	err := common.DBDk.Table("company_wx_bind").Where("type = 2 AND room_id = ? AND status = 1", roomID).Pluck("email", &sendURLs).Error
	if err != nil {
		sendMsgLogger.Errorf("查询发送地址失败: %v", err)
		return err
	}

	if len(sendURLs) == 0 {
		sendMsgLogger.Warnf("未找到群[%s]的有效发送地址", roomID)
		return nil
	}

	msg := TextMessage{
		MsgType: "text",
		Text: struct {
			Content string `json:"content"`
		}{
			Content: message,
		},
	}

	var wg sync.WaitGroup
	var mu sync.Mutex
	var allErrs []string

	maxWorkers := 5
	sem := make(chan struct{}, maxWorkers)

	for _, url := range sendURLs {
		sem <- struct{}{}
		wg.Add(1)
		go func(url string) {
			defer func() {
				<-sem
				wg.Done()
			}()

			for i := 0; i < 3; i++ {
				headers := map[string]string{"Uid": sender}
				if err := utils.SendRequestWithContext(context.Background(), url, "POST", msg, headers, nil); err == nil {
					sendMsgLogger.Infof("发送到 %s 成功", url)
					return
				}
				sendMsgLogger.Warnf("第 %d 次发送到 %s 失败: %v", i+1, url, err)
				time.Sleep(2 * time.Second)
			}

			mu.Lock()
			allErrs = append(allErrs, fmt.Sprintf("发送到 %s 失败", url))
			mu.Unlock()
		}(url)
	}

	wg.Wait()
	close(sem)

	if len(allErrs) > 0 {
		sendMsgLogger.Warnf("部分发送失败: %v", allErrs)
		return fmt.Errorf("部分发送失败: %v", allErrs)
	}

	sendMsgLogger.Infof("发送错误消息到群[%s]用户[%s]: %s", roomID, sender, message)
	return nil
}

// BendiSendFile 发送文件消息函数
func BendiSendFile(roomID, mediaId string) error {
	var sendURLs []string
	err := common.DBDk.Table("company_wx_bind").
		Where("type = 2 AND room_id = ? AND status = 1", roomID).
		Pluck("email", &sendURLs).Error
	if err != nil {
		sendMsgLogger.Errorf("查询文件发送地址失败: %v", err)
		return err
	}

	if len(sendURLs) == 0 {
		sendMsgLogger.Warnf("发送文件，未找到群[%s]的有效发送地址", roomID)
		return nil
	}

	msg := FileMessage{
		MsgType: "file",
		File: struct {
			MediaId string `json:"media_id"`
		}{
			MediaId: mediaId,
		},
	}

	var wg sync.WaitGroup
	var mu sync.Mutex
	var allErrs []string

	maxWorkers := 5
	sem := make(chan struct{}, maxWorkers)

	for _, url := range sendURLs {
		sem <- struct{}{}
		wg.Add(1)
		go func(url string) {
			defer func() {
				<-sem
				wg.Done()
			}()

			for i := 0; i < 3; i++ {
				if err := utils.SendRequestWithContext(context.Background(), url, "POST", msg, nil, nil); err == nil {
					sendMsgLogger.Infof("发送文件，发送到 %s 成功", url)
					return
				}
				sendMsgLogger.Warnf("发送文件，第 %d 次发送到 %s 失败: %v", i+1, url, err)
				time.Sleep(2 * time.Second)
			}

			mu.Lock()
			allErrs = append(allErrs, fmt.Sprintf("发送文件，发送到 %s 失败", url))
			mu.Unlock()
		}(url)
	}

	wg.Wait()
	close(sem)

	if len(allErrs) > 0 {
		sendMsgLogger.Warnf("发送文件，部分发送失败: %v", allErrs)
		return fmt.Errorf("发送文件，部分发送失败: %v", allErrs)
	}

	sendMsgLogger.Infof("发送文件，发送错误消息到群[%s]", roomID)
	return nil
}
